//
//  String+SJHandle.swift
//  SJSwiftKit
//
//  Created by swordjoy on 2017/2/16.
//  Copyright © 2017年 swordjoy. All rights reserved.
//

import Foundation
import UIKit

public extension SJStringProxy {
  
  // MARK: - property
  
  /// 字符串中字符数量
  public var length: Int { return base.count }
  
  /// 字符串中字符数组
  public var array: [String] { return base.description.map { String($0) } }
  
  /// 获取第一个字符
  public var first: String? {
    if array.count > 0 {
      return array[0]
    }
    return nil
  }
  
  /// 一般字母数字用
  public var ASCII: Int {
    if length != 1 { fatalError("(:") }
    return Int(UnicodeScalar(base)!.value)
  }
  
  /// 转换成可读的UUID,无<>, " ", "-"符号
  public var readableUUID: String {
    return base.trimmingCharacters(in: CharacterSet(charactersIn: "<>")).replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "-", with: "")
  }
  
  /// 路径字符串获取文件名
  public var lastPathComponent: String {
    return NSString(string: base).lastPathComponent 
  }
  
  /// 路径或文件字符串获取文件扩展名
  public var pathExtension: String {
    return NSString(string: base).pathExtension 
  }
  
  /// 路径字符串删除文件名后的字符串
  public var deletingLastPathComponent: String {
    return NSString(string: base).deletingLastPathComponent
  }
  
  /// 路径字符串删除文件名扩展名后的字符串
  public var deletingPathExtension: String {
    return NSString(string: base).deletingPathExtension
  }
  
  /// 路径各个部分数组
  public var pathComponents: [String] {
    return NSString(string: base).pathComponents
  }
  
  
  /// 转换成Float
  public var floatValue: Float { return Float(base.sj.doubleValue) }
  
  /// 转换成Int
  public var intValue: Int { return Int(base.sj.doubleValue) }
  
  public var int64Value: Int64? { return Int64(base) }
  
  public var cgFloat: CGFloat {return CGFloat(base.sj.doubleValue) }
  
  /// 转换成Double
  public var doubleValue: Double {
    if let temp = Double(base) { return temp }
    else { return 0 }
  }
  
  /// 转换成data
  public var dataValue: Data? { return base.data(using: .utf8) }
  
  /// 转换成base64编码
  public var base64encoded: String? { return dataValue?.base64EncodedString() }
  
  /// base64解码
  public var base64decoded: String? {
    let data = Data(base64Encoded: base, options: .ignoreUnknownCharacters)
    guard let temp = data else { return nil }
    let dataString = String(data: temp, encoding: .utf8)
    return dataString
  }
  
  /// 百分号编码URL字符串
  public var urlEncoded: String? {
    return base.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed)
  }
  
  // MARK: - function
  
  /// 获取字符串的长度
  ///
  /// - Returns: 字符串长度
  
  /// 截取字符串
  ///
  /// 这里采用的(],左开右闭区间
  ///
  ///  "0123".sj.cut(to: 1)     0
  ///  "0123".sj.cut(from: 1)   123
  ///  "0123".sj.cutString(location: 0, length: 4)    0123
  ///
  /// - Parameters:
  ///   - location: 开始截取位置,0开始
  ///   - length: 结束截取位置
  /// - Returns: 截取后的字符串
  public func cutString(location: Int, length: Int) -> String {
    let len = self.length
    guard (location <= len) && (len - location >= length) else {
      fatalError("beyond endIndex")
    }
    
    let start = base.index(base.startIndex, offsetBy: location)
    let end = base.index(start, offsetBy: length)
    return String(base[start..<end])
  }
  
  /// 截取开始默认为0
  ///
  /// - Parameter to: 结束位置
  /// - Returns: 截取后的字符串
  public func cut(to: Int) -> String {
    return cutString(location: 0, length: to)
  }
  
  
  /// 截取结束默认为字符长
  ///
  /// - Parameter from: 截取开始位置
  /// - Returns: 截取后的字符串
  public func cut(from: Int) -> String {
    let length = self.length - from
    return cutString(location: from, length: length)
  }
  
  /// 路径字符串添加文件(URL代替了)
  ///
  /// - Parameter path: 文件名
  /// - Returns: 添加后的路径
  public func appendingPathComponent(_ path: String) -> String {
    let string = NSString(string: base)
    return string.appendingPathComponent(path)
  }
  
  /// 路径字符串添加扩展名
  ///
  /// - Parameter ext: 扩展名
  /// - Returns: 添加后的字符串
  public func appendingPathExtension(_ ext: String) -> String? {
    let nsSt = NSString(string: base)
    return nsSt.appendingPathExtension(ext)
  }
  
  
  /// 中文转换为拼音
  ///
  /// - Returns: 拼音
  public func chineseToPinYin() -> String {
    let mutableString = NSMutableString(string: base)
    
    if CFStringTransform(mutableString, nil, kCFStringTransformToLatin, false) {
      if CFStringTransform(mutableString, nil, kCFStringTransformStripDiacritics, false) {
        let string = String(mutableString)
        return string.replacingOccurrences(of: " ", with: "")
      }
    }

    return base
  }
    /**
     匹配字符串中所有的URL范围
     */
    public func getAllUrls() -> [NSRange] {
        var urls = [NSRange]()
        // 创建一个正则表达式对象
        do {
            let dataDetector = try NSDataDetector(types:
                NSTextCheckingTypes(NSTextCheckingResult.CheckingType.link.rawValue))
            // 匹配字符串，返回结果集
            let res = dataDetector.matches(in: base,
                                           options: NSRegularExpression.MatchingOptions(rawValue: 0),
                                           range: NSMakeRange(0, base.count))
            // 取出结果
            for checkingRes in res {
                urls.append(checkingRes.range)
            }
        }
        catch {
            print(error)
        }
        return urls
    }
    /**
     匹配字符串中所有的电话范围
     */
    public func getAllPhones() -> [NSRange] {
        var phones = [NSRange]()
        // 创建一个正则表达式对象
        do {
            let dataDetector = try NSDataDetector(types:
                NSTextCheckingTypes(NSTextCheckingResult.CheckingType.phoneNumber.rawValue))
            // 匹配字符串，返回结果集
            let res = dataDetector.matches(in: base,
                                           options: NSRegularExpression.MatchingOptions(rawValue: 0),
                                           range: NSMakeRange(0, base.count))
            // 取出结果
            for checkingRes in res {
                phones.append(checkingRes.range)
            }
        }
        catch {
            print(error)
        }
        return phones
    }
}

public extension SJStringProxy {
    func width(_ font: UIFont) -> CGFloat {
        return self.calculateHeight(CGFloat(MAXFLOAT), font: font, isWidth:true)
    }
    
    func calculateHeight(_ width: CGFloat, height: CGFloat = CGFloat(MAXFLOAT), font: UIFont, lineSpace: CGFloat = 0, isWidth: Bool = false) -> CGFloat {
        var size: CGSize = CGSize.zero
        if base.sj.length > 0 {
            var attributes:[NSAttributedStringKey : Any] = [NSAttributedStringKey.font: font]
            if lineSpace > 0 {
                let style = NSMutableParagraphStyle()
                style.lineSpacing = lineSpace
                attributes[NSAttributedStringKey.paragraphStyle] = style
            }
            
            let frame: CGRect = base.boundingRect(with: CGSize(width: width, height: height), options: [.usesLineFragmentOrigin], attributes: attributes, context: nil)
            size = CGSize(width: frame.size.width, height: frame.size.height + 1)
        }
        return isWidth ? size.width : size.height
    }
    
    
}
